#include "stdafx.h"
#include "xElement.h"
#include "xTextNode.h"
#include "xAttribute.h"

#include "zDefine.h"
#include "ckFunction.h"


namespace ck
{
	namespace xml
	{
		Element::Element(xmlNodePtr pxNode):
		Node(pxNode)
		{
		}


		Element::~Element()
		{
		}

		Attribute* Element::SetAttribute(const char* name, const char* value, const char* nmspace/*= NULL*/, bool encoding/* = false*/)
		{
			xmlAttr* attr = NULL;

			if ((nmspace == NULL) || strlen(nmspace) == 0)
			{
				if (encoding)
				{
					size_t size_utf8 = Z_PATH_MAX;
					char name_utf8[Z_PATH_MAX];
					char value_utf8[Z_PATH_MAX];
					memset(name_utf8, 0, Z_PATH_MAX);
					memset(value_utf8, 0, Z_PATH_MAX);
					ck_encoding_convert_2("GBK", "UTF-8", name, strlen(name), (char*)name_utf8, &size_utf8);
					ck_encoding_convert_2("GBK", "UTF-8", value, strlen(value), (char*)value_utf8, &size_utf8);
					attr = xmlSetProp(m_pxNode, (const xmlChar*)name_utf8, (const xmlChar*)value_utf8);
				}
				else
				{
					attr = xmlSetProp(m_pxNode, (const xmlChar*)name, (const xmlChar*)value);
				}
			}
			else
			{
				//If the namespace exists, then use it:
				xmlNs* ns = xmlSearchNs(m_pxNode->doc, m_pxNode, (const xmlChar*)nmspace);
				if (ns)
				{
					//if (encoding)
					//{
					//	size_t size_utf8 = 0;
					//	char name_utf8[Z_PATH_MAX];
					//	char value_utf8[Z_PATH_MAX];
					//	memset(name_utf8, 0, Z_PATH_MAX);
					//	memset(value_utf8, 0, Z_PATH_MAX);
					//	auge_encoding_convert_2("GBK", "UTF-8", name, strlen(name), (char*)name_utf8, &size_utf8);
					//	auge_encoding_convert_2("GBK", "UTF-8", value, strlen(value), (char*)value_utf8, &size_utf8);
					//	attr = xmlSetProp(m_pxNode, (const xmlChar*)name_utf8, (const xmlChar*)value_utf8);
					//}
					//else
					{
						attr = xmlSetNsProp(m_pxNode, ns, (const xmlChar*)name, (const xmlChar*)value);
					}
					//attr = xmlSetNsProp(m_pxNode, ns, (const xmlChar*)name_utf8, (const xmlChar*)value_utf8);
				}
				else
				{
				}
			}

			if (attr)
			{
				return reinterpret_cast<Attribute*>(attr->_private);
			}
				
			return NULL;
		}

		Attribute* Element::GetAttribute(const char* name, const char* nmspace/*= NULL*/)
		{
			if (name == NULL)
			{
				return NULL;
			}

			//const char* name_utf8 = name;
			const char* name_utf8 = ck_encoding_convert("GBK", "UTF-8", name, strlen(name));
			if (name_utf8 == NULL)
			{
				return NULL;
			}

			if (nmspace == NULL)
			{
				xmlAttr* attr = xmlHasProp(const_cast<xmlNode*>(m_pxNode), (const xmlChar*)name_utf8);
				if (attr)
				{
					return reinterpret_cast<Attribute*>(attr->_private);
				}
			}
			else
			{
				//const char* ns_uri = GetNamespaceUriForPrefix(ns_prefix);
				//xmlAttr* attr = xmlHasNsProp(const_cast<xmlNode*>(m_pxNode),
				//	(const xmlChar*)name_utf8,
				//	(const xmlChar*)ns_uri);
				//if (attr)
				//{
				//	return reinterpret_cast<XAttribute*>(attr->_private);
				//}
			}

			return NULL;
		}

		z_int32 Element::SetContent(const z_char* szContent, bool enccoding/*=true*/)
		{
			if (szContent == NULL)
			{
				return RC_FAILURE;
			}

			TextNode* pTextNode = GetChildTextNode();
			if (pTextNode != NULL)
			{
				pTextNode->SetContent(szContent);
			}
			else
			{
				AddChildText(szContent, enccoding);
			}

			return RC_SUCCESS;
		}

		const z_char* Element::GetContent()
		{
			return NULL;
		}

		TextNode* Element::AddChildText(const z_char* szContent, bool encoding/*=true*/)
		{
			if (m_pxNode->type != XML_ELEMENT_NODE)
			{
				return NULL;
			}

			xmlNode* node = NULL;
			size_t content_len = strlen(szContent);
			if (content_len > 0)
			{
				if (encoding)
				{
					size_t size_utf8 = content_len << 1;

					char* content_utf8 = new char[size_utf8];
					memset(content_utf8, 0, size_utf8);
					ck_encoding_convert_2("GBK", "UTF-8", szContent, content_len, (char*)content_utf8, &size_utf8);
					node = xmlNewText((const xmlChar*)content_utf8);
					delete[] content_utf8;
				}
				else
				{
					node = xmlNewText((const xmlChar*)szContent);
				}
			}
			else
			{
				node = xmlNewText((const xmlChar*)"");
			}

			node = xmlAddChild(m_pxNode, node);

			return static_cast<TextNode*>(node->_private);
		}


	}
}


